Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve multi_field syntax #4521

Closed
clintongormley opened this issue Dec 19, 2013 · 22 comments
Closed

Improve multi_field syntax #4521

clintongormley opened this issue Dec 19, 2013 · 22 comments

Comments

@clintongormley
Copy link

Proposed syntax for multi_field

Any field type (other than object, nested) should accept a fields parameter which defines any extra fields that should be indexed. So for example a simple field like:

{
    "title": {
        "type": "string"
}}

can be converted into a multi-field by adding a fields parameter:

{
    "title": {
        "type": "string",
        "fields": {
            "raw": { "type": "string", "index": "not_analyzed" }
       }
}}
@ghost ghost assigned martijnvg Dec 23, 2013
martijnvg added a commit to martijnvg/elasticsearch that referenced this issue Jan 10, 2014
…hat can be set on any core field.

When upgrading to ES 1.0 the existing mappings with a multi-field type automatically get replaced to a core field with the new `fields` opt

Closes to elastic#4521
martijnvg added a commit that referenced this issue Jan 13, 2014
…hat can be set on any core field.

When upgrading to ES 1.0 the existing mappings with a multi-field type automatically get replaced to a core field with the new `fields` option.

If a `multi_field` type-ed field doesn't have a main / default field, a default field will be chosen for the multi fields syntax. The new main field type
will be equal to the first `multi_field` fields' field or type string if no fields have been configured for the `multi_field` field and in both cases
the default index will not be indexed (`index=no` is set on the default field).

If a `multi_field` typed field has a default field, that field will replace the `multi_field` typed field.

Closes to #4521
@clintongormley
Copy link
Author

Moved the path part of the issue to to #4729

@martijnvg
Copy link
Member

Pushed to master via: 943b626

brusic pushed a commit to brusic/elasticsearch that referenced this issue Jan 19, 2014
…hat can be set on any core field.

When upgrading to ES 1.0 the existing mappings with a multi-field type automatically get replaced to a core field with the new `fields` option.

If a `multi_field` type-ed field doesn't have a main / default field, a default field will be chosen for the multi fields syntax. The new main field type
will be equal to the first `multi_field` fields' field or type string if no fields have been configured for the `multi_field` field and in both cases
the default index will not be indexed (`index=no` is set on the default field).

If a `multi_field` typed field has a default field, that field will replace the `multi_field` typed field.

Closes to elastic#4521
@apatrida
Copy link
Contributor

It isn't clear if the settings inheritance works, for example if "type" is left out of the sub-field, it produces an error:

{"error":"MapperParsingException[mapping [default]]; nested: MapperParsingException[No type specified for property [stopped_fuzzy_metaphone]]; ","status":400}

So does that work, or just not for type (therefore the sample is wrong). What settings inherit, which do not?

@martijnvg
Copy link
Member

@jaysonminard The settings inheriting didn't get in. For some reason I forgot to update the issue description and documentation. I'll update this now.

@apatrida
Copy link
Contributor

@martijnvg

Ok, but the default field being from the root still works ok? For example:

{
    "title": {
        "type": "string",
        "fields": {
            "raw": { "type": "string", "index": "not_analyzed" }
       }
  }
}

produces title and title.raw?

@martijnvg
Copy link
Member

Yes, that produces a title and a title.raw field.

@apatrida
Copy link
Contributor

ok, with a field pushing content to one of these (a source field using copy_to into a dest multi-field), I am not getting the expected results, will try a small experiment to see more specifically what is going on.

@martijnvg
Copy link
Member

If your document looks like this:

{
    "title" : "my title"
}

and using the above mapping snippet should yield two fields a title and title.raw field.

@apatrida
Copy link
Contributor

either copy_to doesn't work, or it doesn't work in conjunction with this. 1 moment for example

@apatrida
Copy link
Contributor

ok, don't know where I got the idea that copy_to was in 1.0.0.RC1, maybe only on master (the docs are only for 0.90 branch or master, there are no 1.0.0.RC1 specific docs?). That is the cause of my problem, using something allowed by mappings parser, but doesn't actually work. I'll go back to full names and using path variable to make the copies.

"title": {
            "type": "string",
            "index": "no",
            "store": "no",
            "copy_to" : [ "search_title", "search_combined", "other_title" ],
            "fielddata": {
                "format": "disabled"
            }
        },

...
"search_title": {
            "type": "string",
            "index": "analyzed",
            "fields": {
                "raw": {
                    "type": "string",
                    "index": "not_analyzed"
                }
            }
        },

@martijnvg
Copy link
Member

Yes, copy_to isn't in 1.0.0.RC1 and there are no rc1 specific docs... there will be specific docs for 1.0 when 1.0.0.GA gets out.

@apatrida
Copy link
Contributor

Ok, that makes it hard to test 1.0.0.RC1 with 1.0.0.RC1 features. The release candidate isn't the main download link, has no docs, and seems like it could use more attention getting markers so that it is heavily tested before GA.

By the way, this link related to this actual issue (multi fields docs) on master is broken:
http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/multi-fields.html

(linked to from: http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/mapping.html)

So there is not current multi-field docs that I can find.

@martijnvg
Copy link
Member

I just removed that specific link from the documentation and added the multi fields documentation to the core types page: http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/mapping-core-types.html#_multi_fields_3

I guess this must be some browser cache, that showed the old link.

@martijnvg
Copy link
Member

Also I'll annotate the multi fields and copy to with the right version, in order to avoid confusion.

@apatrida
Copy link
Contributor

Ok. Without copy_to there is no way to do what I wanted. Path of "just_name" affects all 'children' of the mutli-field, when I only want one of them to go to the just_name and the rest to be suffixes. path only applies at the top level of the field yes, and can't change for just one of the multi-values?

or can the name include a period. so that TITLE could go to TITLE, TITLE.NOSTOP, TITLE.EXACT, and ALL_TITLES at the same time without changing the input JSON.

@martijnvg
Copy link
Member

Yes, path applies to all multi fields of a core field, but you can define another fields inside another fields. I think that something like this will result into something that you want:

curl -XPUT "http://localhost:9200/test1" -d'
{
    "mappings": {
        "test1" : {
            "properties": {
                "title" : {
                    "type": "string",
                    "fields": {
                        "raw" : {
                            "type": "string"
                        },
                        "search_title" : {
                            "type" : "string",
                            "index": "no", 
                            "path": "just_name",
                            "fields" : {
                                "x" : {
                                    "type": "string",
                                    "index_name": "search_title"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}'

But this way more verbose and less readable than when copy_to is used.

@apatrida
Copy link
Contributor

Ok, the default field doesn't actually work right. (not related to copy_to)

 "content_cleaned": {
                    "type": "string",
                    "index": "analyzed",
                    "analyzer": "SearchWithSpecials",
                    "store": false,
                    "norms.enabled": true,
                    "term_vector": "with_positions_offsets",
                    "fielddata": {
                        "format": "disabled"
                    },
                    "fields": {
                        "stopped": {
                            "analyzer": "SearchWithSpecials",
                            "type": "string",
                            "index": "analyzed",
                            "store": false,
                            "norms.enabled": true,
                            "term_vector": "with_positions_offsets",
                            "fielddata": {
                                "format": "disabled"
                            }
                        },
...

note that content_cleaned and content_cleaned.stopped should do the same thing but content_cleaned is not searchable for a word, that is found when searching content_cleaned.stopped. So the base default field doesn't work unless repeated within the fields list.

@apatrida
Copy link
Contributor

Doing this, does not resolve the problem that content_cleaned does not find words that content_cleaned.stopped finds (although their declaration is the same):

 "content_cleaned": {
                    "type": "string",
                    "index": "analyzed",
                    "analyzer": "SearchWithSpecials",
                    "store": false,
                    "norms.enabled": true,
                    "term_vector": "with_positions_offsets",
                    "fielddata": {
                        "format": "disabled"
                    },
                    "fields": {
                        "content_cleaned": {
                            "analyzer": "SearchWithSpecials",
                            "type": "string",
                            "index": "analyzed",
                            "store": false,
                            "norms.enabled": true,
                            "term_vector": "with_positions_offsets",
                            "fielddata": {
                                "format": "disabled"
                            }
                        },
                        "stopped": {
                            "analyzer": "SearchWithSpecials",
                            "type": "string",
                            "index": "analyzed",
                            "store": false,
                            "norms.enabled": true,
                            "term_vector": "with_positions_offsets",
                            "fielddata": {
                                "format": "disabled"
                            }
                        },
...

@martijnvg
Copy link
Member

I'm lost on what you're trying to achieve. Can you share a full example (via gist or something like that), with the mapping you're creating, index a sample document and search requests you expect to work.

@apatrida
Copy link
Contributor

I figured it out, had a type specific override breaking the mappings that I changed, had to change it as well. All good, wrote a test case that covered the normal usage and it worked fine.

@s1monw
Copy link
Contributor

s1monw commented Jan 22, 2014

if you wanna contribute that testcase that is always welcome as well! just open a PR

@apatrida
Copy link
Contributor

Of course, thanks Simon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants